﻿#ifndef __SS_OBJECT_H__
#define __SS_OBJECT_H__
#include <string>

namespace StarSeeker
{

class ssClassFeild;
class ssObject
{
public:
	ssObject();
	ssObject(const char* name);
	virtual ~ssObject();

	size_t GetFiledCount();
	ssClassFeild* GetFeild(size_t pos);
	ssClassFeild* GetFeild(const std::string& feildName);

	template<typename T>
	void Get(const std::string& feildName, T& value);
	template<typename T>
	void Set(const std::string& feildName, const T& value);
	void Set(const std::string& feildName, const char* value);

	template <typename R = void, typename ...Args>
	R Call(const std::string& methodName, Args&&... args);
public:
	std::string		m_className;
};

template<typename T>
inline void ssObject::Get(const std::string & feildName, T & value)
{
	ssClassFeild* feild = ssSingle<ssClassFactory>::instance()->GetFeild(m_className, feildName);
	value = *(T*)((unsigned char*)(this) + feild->Offset());
}

template<typename T>
inline void ssObject::Set(const std::string & feildName, const T & value)
{
	ssClassFeild* feild = ssSingle<ssClassFactory>::instance()->GetFeild(m_className, feildName);
	*(T*)((unsigned char*)(this) + feild->Offset()) = value;
}

template<typename R, typename ...Args>
inline R ssObject::Call(const std::string & methodName, Args && ...args)
{
	ssClassMethod* method = ssSingle<ssClassFactory>::instance()->GetMethod(m_className, methodName);
	typedef std::function<R(decltype(this), Args...)> class_method;
	return (*((class_method*)method->Method()))(this, args...);
}

}
#endif
